using Microsoft.EntityFrameworkCore; // 引入 EF Core 命名空间
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using MyHomeworkWebAPi.Models;
using MyHomeworkWebAPi.Models.ef;
using MyHomeworkWebAPi.Models.Request;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace MyHomeworkWebAPi.Services
{
    /// <summary>
    /// 用户服务实现类
    /// </summary>
    public class UserServices : IUserServices
    {
        private readonly Models.ef.SecondHandTradingPlatformContext _context;
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 构造函数，注入数据库上下文和配置
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="configuration">配置</param>
        public UserServices(Models.ef.SecondHandTradingPlatformContext context, IConfiguration configuration)
        {
            _context = context;
            _configuration = configuration;
        }

        /// <summary>
        /// 获取所有用户列表
        /// </summary>
        /// <returns>用户列表</returns>
        public async Task<List<Models.ef.User>> GetAllAsync()
        {
            return await _context.Users.ToListAsync();
        }

        /// <summary>
        /// 根据ID获取用户
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>用户信息</returns>
        public async Task<Models.ef.User?> GetByIdAsync(Guid userId)
        {
            return await _context.Users.FindAsync(userId);
        }

        /// <summary>
        /// 检查学号是否已存在
        /// </summary>
        /// <param name="studentId">学号</param>
        /// <returns>true表示已存在，false表示不存在</returns>
        public async Task<bool> IsStudentIdExistsAsync(string studentId)
        {
            return await _context.Users.AnyAsync(u => u.StudentId == studentId);
        }

        /// <summary>
        /// 检查用户名是否已存在
        /// </summary>
        /// <param name="nickname">用户名</param>
        /// <returns>true表示已存在，false表示不存在</returns>
        public async Task<bool> IsNicknameExistsAsync(string nickname)
        {
            return await _context.Users.AnyAsync(u => u.Nickname == nickname);
        }

        /// <summary>
        /// 检查手机号是否已存在
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <returns>true表示已存在，false表示不存在</returns>
        public async Task<bool> IsPhoneExistsAsync(string phone)
        {
            return await _context.Users.AnyAsync(u => u.Phone == phone);
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="model">登录信息</param>
        /// <returns>JWT令牌</returns>
        public async Task<string> LoginAsync(LoginModel model)
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.StudentId == model.StudentId);
            if (user == null)
            {
                throw new Exception("学号或密码错误");
            }

            if (!PasswordHasher.VerifyPassword(model.Password, user.Password))
            {
                throw new Exception("学号或密码错误");
            }

            return GenerateJwtToken(user);
        }

        /// <summary>
        /// 注册新用户
        /// </summary>
        /// <param name="request">用户注册请求信息</param>
        /// <returns>新创建的用户信息</returns>
        public async Task<Models.ef.User> RegisterAsync(UserRegisterRequest request)
        {
            // 检查学号是否已被注册
            if (await IsStudentIdExistsAsync(request.StudentId))
            {
                throw new Exception("学号已被注册");
            }

            // 检查用户名是否已被使用
            if (await IsNicknameExistsAsync(request.Nickname))
            {
                throw new Exception("用户名已被使用");
            }

            // 检查手机号是否已被注册
            if (await IsPhoneExistsAsync(request.Phone))
            {
                throw new Exception("手机号已被注册");
            }

            // 创建新用户对象
            var user = new Models.ef.User
            {
                UserId = Guid.NewGuid(),
                StudentId = request.StudentId,
                Nickname = request.Nickname,
                Password = PasswordHasher.HashPassword(request.Password),
                Phone = request.Phone,
                Avatar = request.Avatar ?? "default.jpg"
            };

            // 添加到数据库
            await _context.Users.AddAsync(user);
            // 保存更改
            await _context.SaveChangesAsync();

            return user;
        }

        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns>JWT令牌字符串</returns>
        private string GenerateJwtToken(Models.ef.User user)
        {
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()),
                new Claim(ClaimTypes.Name, user.Nickname),
                new Claim("StudentId", user.StudentId)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]!));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(30),
                signingCredentials: creds
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        /// <summary>
        /// 更新用户昵称
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="newNickname">新昵称</param>
        /// <returns>更新后的用户信息</returns>
        public async Task<Models.ef.User> UpdateNicknameAsync(Guid userId, string newNickname)
        {
            var user = await _context.Users.FindAsync(userId) 
                ?? throw new Exception("用户不存在");

            if (await IsNicknameExistsAsync(newNickname))
            {
                throw new Exception("昵称已被使用");
            }

            user.Nickname = newNickname;
            await _context.SaveChangesAsync();
            return user;
        }

        /// <summary>
        /// 更新用户手机号
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="newPhone">新手机号</param>
        /// <returns>更新后的用户信息</returns>
        public async Task<Models.ef.User> UpdatePhoneAsync(Guid userId, string newPhone)
        {
            var user = await _context.Users.FindAsync(userId)
                ?? throw new Exception("用户不存在");

            if (await IsPhoneExistsAsync(newPhone))
            {
                throw new Exception("手机号已被使用");
            }

            user.Phone = newPhone;
            await _context.SaveChangesAsync();
            return user;
        }

        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="oldPassword">旧密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>更新后的用户信息</returns>
        public async Task<Models.ef.User> UpdatePasswordAsync(Guid userId, string oldPassword, string newPassword)
        {
            var user = await _context.Users.FindAsync(userId)
                ?? throw new Exception("用户不存在");

            if (!PasswordHasher.VerifyPassword(oldPassword, user.Password))
            {
                throw new Exception("旧密码不正确");
            }

            user.Password = PasswordHasher.HashPassword(newPassword);
            await _context.SaveChangesAsync();
            return user;
        }

        /// <summary>
        /// 更新用户头像
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="newAvatar">新头像文件名</param>
        /// <returns>更新后的用户信息</returns>
        public async Task<Models.ef.User> UpdateAvatarAsync(Guid userId, string newAvatar)
        {
            var user = await _context.Users.FindAsync(userId)
                ?? throw new Exception("用户不存在");

            user.Avatar = newAvatar;
            await _context.SaveChangesAsync();
            return user;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>删除是否成功</returns>
        public async Task<bool> DeleteAsync(Guid userId)
        {
            var user = await _context.Users.FindAsync(userId);
            if (user == null)
            {
                return false;
            }

            _context.Users.Remove(user);
            await _context.SaveChangesAsync();
            return true;
        }
    }
}



